package com.controller;

import com.common.paging.PagingData;
import com.dto.excution.LoginExcution;
import com.dto.in.AddRecordDto;
import com.entity.*;
import com.enums.LoginEnum;
import com.service.AdvicesService;
import com.service.SelectFormService;
import com.util.UUIDUtil;
import com.util.WxPaySignatureUtils;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * Created by Administrator on 2018/10/20.
 */
@RestController
@RequestMapping("Advices")
public class AdvicesController {

    @Autowired
    private AdvicesService advicesService;

    @Autowired
    private SelectFormService selectFormService;

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }

    @ApiOperation(value = "投诉建议")
    @PostMapping(value = "/suggestion")
    @ResponseBody
    public String Advices(String userId, String phone, String title, String content) {
        int res = advicesService.advice(userId, phone, title, content);
        if (res == 1) {
            return "提交成功";
        } else {
            return "提交失败";
        }
    }

    @ApiOperation(value = "插入评价")
    @PostMapping(value = "/addEvaluation")
    @ResponseBody
    public int addEvaluation(Integer recordId, Integer stdUserId, Integer stdId, Integer teaUserId, Integer evaluationNum) {
        int res = advicesService.addEvaluation(recordId, stdUserId, stdId, teaUserId, evaluationNum);
        if (res > 0) {
            return 1;
        } else {
            return 0;
        }
    }

    @ApiOperation(value = "后台/查询所有投诉建议")
    @PostMapping(value = "/findAdvicesList")
    @ResponseBody
    public PagingData findAdvicesList(Integer page, Integer length) {
        page = (page - 1) * 10;
        PagingData list = advicesService.findAdvicesList(page, length);
        return list;
    }

    @ApiOperation(value = "后台/删除投诉建议")
    @PostMapping(value = "/setAdvices")
    @ResponseBody
    public LoginExcution<Void> setAdvices(Integer id) {
        int success = advicesService.setAdvices(id);
        if (success > 0) {
            return new LoginExcution<Void>(null, LoginEnum.SUCCESS);
        } else {
            return new LoginExcution<Void>(null, LoginEnum.FAIL);
        }
    }

    @ApiOperation(value = "状态区分订单")
    @PostMapping(value = "/findUseStatus")
    @ResponseBody
    public List<Record> findStatus(String stdUserId, String teaUserId, String teaId, String type, Integer limit) {
        return advicesService.findReadyStatus(stdUserId, teaUserId, teaId, type, limit);
    }

    @ApiOperation(value = "开始上课/修改订单状态")
    @PostMapping(value = "/updateRecordStatus")
    @ResponseBody
    public int updateRecordStatus(Integer id) {
        int i = advicesService.updateRecordStatus(id);
        if (i > 0) {
            return i;
        } else {
            return 0;
        }
    }

    @ApiOperation(value = "创建订单")
    @PostMapping(value = "/createRecord")
    @ResponseBody
    public int createRecord(AddRecordDto addRecordDto) {
        int i = advicesService.createRecord(addRecordDto);
        if (i > 0) {
            return i;
        } else {
            return 0;
        }
    }

    @ApiOperation(value = "创建子订单")
    @PostMapping(value = "/createRecordOrder")
    @ResponseBody
    public int createRecordOrder(Integer recordId, Integer fewHours, BigDecimal fewHoursPrice) {
        int i = advicesService.createRecordOrder(recordId, fewHours, fewHoursPrice);
        if (i > 0) {
            return i;
        } else {
            return 0;
        }
    }

    @ApiOperation(value = "确认下课/查看是否是第一个或者最后一个")
    @PostMapping(value = "/findRecordOrderSeveral")
    @ResponseBody
    public int findRecordOrderSeveral(Integer id, Integer recordId) {
        return advicesService.findRecordOrderSeveral(id, recordId);
    }

    @ApiOperation(value = "上课中点击获取订单下的小订单")
    @PostMapping(value = "/findRecordOrder")
    @ResponseBody
    public List<RecordOrderInfo> findRecordOrder(Integer recordId) {
        return advicesService.findRecordOrder(recordId);
    }

    @ApiOperation(value = "查询多少人申请我")
    @PostMapping(value = "/findAppliedCount")
    @ResponseBody
    public int findAppliedCount(Integer stdUserId, Integer stdId) {
        return advicesService.findAppliedCount(stdUserId, stdId);
    }

    @ApiOperation(value = "取消订单")
    @PostMapping(value = "/cancelOrder")
    @ResponseBody
    public int cancelOrder(Integer id) {
        return advicesService.cancelOrder(id);
    }

    @ApiOperation(value = "ID查订单")
    @PostMapping(value = "/findRecordById")
    @ResponseBody
    public Record findRecordById(Integer id) {
        Record record = advicesService.findRecordById(id);
        return record;
    }

    @ApiOperation(value = "修改支付状态")
    @PostMapping(value = "/updatePayStatus")
    @ResponseBody
    public String updatePayStatus(Integer id, String nonceStr) {
        int i = advicesService.updatePayStatus(id, nonceStr);
        if (i > 0) {
            return "修改成功";
        } else {
            return "修改失败";
        }
    }

    @ApiOperation(value = "查当前老师的所有课程价格")
    @PostMapping(value = "/findPrice")
    @ResponseBody
    public List<Price> findPrice(Integer userId) {
        List<Price> prices = advicesService.findPrice(userId);
        return prices;
    }

    @ApiOperation(value = "查询流水")
    @PostMapping(value = "/findBill")
    @ResponseBody
    public List<bill> findBill(Integer userId, String type) { //type=0是转入，1支出
        List<bill> bill = advicesService.findBill(userId, type);
        return bill;
    }

    @ApiOperation(value = "修改退款申请状态") //退款时调用此接口
    @PostMapping(value = "/updateOrderStatus")
    @ResponseBody
    public String updateOrderStatus(String id, String operation) {  //0是新申请，1是已处理 ，2是查询退款状态
        int i = advicesService.updateOrderStatus(id, operation);
        if (operation.equals("2"))
            switch (i) {
                case 0:
                    return "未申请";
                case 2:
                    return "已处理";
                case 3:
                    return "新申请";
                default:
                    return "查询出错";
            }
        else if (i > 0) {
            return "操作成功";
        } else {
            return "操作失败";
        }
    }

    @ApiOperation(value = "添加退款申请") //退款时调用此接口
    @PostMapping(value = "/addRefund")
    @ResponseBody
    public int addRefund(Integer recordId) {
        return advicesService.addRefund(recordId);
    }


    @ApiOperation(value = "添加提现申请")
    @PostMapping(value = "/addMoneyRequest")
    @ResponseBody
    public String addMoneyRequest(String userId, String realName, BigDecimal money, String bankCardId,String cPhone,String cType) {
        int i = advicesService.addMoneyRequest(userId, realName, money, bankCardId,cPhone,cType);
        if (i > 0) {
            return "操作成功";
        } else {
            return "操作失败";
        }
    }

    @ApiOperation(value = "修改提现申请状态")
    @PostMapping(value = "/updateMoneyRequestStatus")
    @ResponseBody
    public String updateMoneyRequestStatus(Integer userId, String realName, BigDecimal money, String bankCardId) {
        int i = advicesService.updateMoneyRequestStatus(userId, realName, money, bankCardId, UUIDUtil.get32UUID());
        if (i > 0) {
            return "提现成功";
        } else {
            return "提现失败";
        }

    }

    @ApiOperation(value = "接受支付结果")
    @PostMapping(value = "/payResult")
    @ResponseBody
    public String payResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("utf-8");
        StringBuffer xmlStr = new StringBuffer();
        BufferedReader reader = request.getReader();
        String line = null;
        while ((line = reader.readLine()) != null) {
            xmlStr.append(line);
        }
        String result = xmlStr.toString();
        File file = new File("C:" + File.separator + "test.txt");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        //2：准备输出流
        Writer out = new FileWriter(file);
        out.write(result);
        out.close();
        Map res = xmlString2Map(result);
        String nonceStr = (String) res.get("nonce_str");
        String transaction_id = (String) res.get("transaction_id");  //微信支付订单号
        String out_trade_no = (String) res.get("out_trade_no");    //商户订单号
        String payTime = (String) res.get("time_end");    //支付时间
        int i = advicesService.updataPayMessage(transaction_id, out_trade_no, nonceStr, payTime);
        if (i > 0)
            return "<xml>   <return_code><![CDATA[SUCCESS]]></return_code>  <return_msg><![CDATA[OK]]></return_msg></xml>     ";
        else
            return "<xml>   <return_code><![CDATA[FAIL]]></return_code>  <return_msg><![CDATA订单没有交易单号]></return_msg></xml>     ";
    }

    @ApiOperation(value = "修改课程价格")
    @PostMapping(value = "/updataSubjectPrice")
    @ResponseBody
    public String updataSubjectPrice(Integer userId, Integer teacherId, HttpServletRequest request) {
        String ds = request.getParameter("subjectData");
        JSONArray json = JSONArray.fromObject(ds);
        List<SubjectDataInfo> subjectData = JSONArray.toList(json, new SubjectDataInfo(), new JsonConfig());
        int i = advicesService.updataSubjectPrice(userId, teacherId, subjectData);
        if (i > 0) {
            return "操作成功";
        } else {
            return "操作失败";
        }
    }

    //以下为支付所需接口和函数
    @ApiOperation(value = "支付")
    @PostMapping(value = "/pay")
    @ResponseBody
    public Map pay(HttpServletRequest request, String userId, String money) throws Exception {
        request.setCharacterEncoding("utf-8");
        String openid = selectFormService.findOpenId(userId);
        System.out.println(openid);
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        Map<String, String> map = new TreeMap<String, String>();
        map.put("appid", "wx1a47bb9e4089c8e2");
        map.put("body", "lyjj-CoursePurchase");
        map.put("mch_id", "1519287851");
        String uuid = UUIDUtil.get32UUID();
        map.put("nonce_str", uuid); // 随机串
        System.out.println(uuid);
        map.put("notify_url", "https://www.lingyingjiajiao.com/lyjj/Advices/payResult");// 通知URL地址
        map.put("openid", openid);// 用户微信唯一标识
        String time = String.valueOf(Calendar.getInstance().getTimeInMillis());
        map.put("out_trade_no", time);//此参数填写订单的时间戳
        String ip = findIP(request);
        map.put("spbill_create_ip", ip); //用户端的IP地址
        map.put("total_fee", money);// 此参数为订单金额
        map.put("trade_type", "JSAPI");
        String str = WxPaySignatureUtils.signature(map, "yutongkejilingyingjiajiao2018100");
        System.out.println(str);
        map.put("sign", str); //签名
        System.out.println(map2xml(map));
        ResponseEntity<String> responseEntity =
                restTemplate().postForEntity(url, map2xml(map), String.class);
        System.out.println("pay" + responseEntity.getBody());
        Map m = xmlString2Map(responseEntity.getBody());
        Map<String, String> map2 = new TreeMap<String, String>();
        map2.put("appId", "wx1a47bb9e4089c8e2");
        map2.put("nonceStr", uuid);
        System.out.println(m.get("prepay_id"));
        map2.put("package", "prepay_id=" + m.get("prepay_id"));
        map2.put("signType", "MD5");
        map2.put("timeStamp", time);
        String twoSign = WxPaySignatureUtils.signature(map2, "yutongkejilingyingjiajiao2018100");
        map2.put("paySign", twoSign);
        return map2;

    }

    public static String map2xml(Map<String, String> map) throws Exception {
        StringBuffer sb = new StringBuffer("");
        sb.append("<xml>");
        Set<String> set = map.keySet();
        for (Iterator<String> it = set.iterator(); it.hasNext(); ) {
            String key = it.next();
            Object value = map.get(key);
            if (!key.equals("sign")) {
                sb.append("<").append(key).append(">").append("<![CDATA[");
                sb.append(value);
                sb.append("]]>").append("</").append(key).append(">");
            } else {
                sb.append("<").append(key).append(">");
                sb.append(value);
                sb.append("</").append(key).append(">");
            }
        }
        sb.append("</xml>");
        return sb.toString();

    }

    public static Map<String, Object> xmlString2Map(String xmlStr) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        Document doc = DocumentHelper.parseText(xmlStr);
        Element el = doc.getRootElement();
        map = recGetXmlElementValue(el, map);
        return map;
    }

    @SuppressWarnings({"unchecked"})
    private static Map<String, Object> recGetXmlElementValue(Element ele, Map<String, Object> map) {
        List<Element> eleList = ele.elements();
        if (eleList.size() == 0) {
            map.put(ele.getName(), ele.getTextTrim());
            return map;
        } else {
            for (Iterator<Element> iter = eleList.iterator(); iter.hasNext(); ) {
                Element innerEle = iter.next();
                recGetXmlElementValue(innerEle, map);
            }
            return map;
        }
    }

    //查询客户端IP地址。
    public static String findIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    //以上为支付所需接口
}
